﻿using System;
using System.Text;
using System.Windows.Forms;

namespace MyFastDataSourceBind
{
    /// <summary>
    /// 可绑定到数据源的图片框控件
    /// </summary>
    /// <remarks>编制 袁永福</remarks>
    public class XDBPictureBox : System.Windows.Forms.PictureBox, IXDataSourceable
    {
        /// <summary>
        /// 初始化对象
        /// </summary>
        public XDBPictureBox()
        {
        }

        private string strXDataFieldName = null;
        /// <summary>
        /// 绑定的数据源的字段名
        /// </summary>
        [System.ComponentModel.Editor(
            typeof(XDataFieldNameEditor),
            typeof(System.Drawing.Design.UITypeEditor))]
        public string XDataFieldName
        {
            get { return strXDataFieldName; }
            set { strXDataFieldName = value; }
        }

        private string strXDataSourceName = null;
        /// <summary>
        /// 按钮操作的数据源名称
        /// </summary>
        [System.ComponentModel.Editor(
            typeof(XDataSourceNameEditor),
            typeof(System.Drawing.Design.UITypeEditor))]
        public string XDataSourceName
        {
            get
            {
                return strXDataSourceName;
            }
            set
            {
                strXDataSourceName = value;
                XDataSourceEventSender.Register(this, strXDataSourceName);
            }
        }

        private bool bolReadonly = false;
        /// <summary>
        /// 内容是否只读
        /// </summary>
        [System.ComponentModel.DefaultValue(false)]
        public bool Readonly
        {
            get { return bolReadonly; }
            set { bolReadonly = value; }
        }
        /// <summary>
        /// 处理鼠标双击事件，加载图片内容
        /// </summary>
        /// <param name="e">事件参数</param>
        protected override void OnDoubleClick(EventArgs e)
        {
            base.OnDoubleClick(e);
            if (this.Readonly == false)
            {
                // 若内部不是只读的，则弹出图片文件选择对话框
                // 让用户选择输入一个图片文件名，然后加载该图片
                // 文件并设置为显示的图片数据。
                using (OpenFileDialog dlg = new OpenFileDialog())
                {
                    dlg.Filter = "图片文件|*.bmp;*.jpg;*.jpeg;*.png;*.gif|所有文件|*.*";
                    dlg.CheckFileExists = true;
                    if (dlg.ShowDialog(this) == DialogResult.OK)
                    {
                        this.Image = System.Drawing.Image.FromFile(dlg.FileName);
                    }
                }
            }
        }

        /// <summary>
        /// 销毁对象，撤销数据源绑定
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            XDataSourceEventSender.UnRegister(this);
        }

        /// <summary>
        /// 处理数据源事件
        /// </summary>
        /// <param name="Sender">事件参数</param>
        /// <param name="Args">事件参数</param>
        public void HandleDataSourceEvent(object Sender, XDataSourceEventArgs Args)
        {
            switch (Args.Style)
            {
                case XDataSourceEventStyle.FillUI:
                    // 处理FillUI事件
                    // 若数据源不处于编辑状态则控件数据只读
                    this.Readonly = !Args.DataSource.Editing;
                    System.Drawing.Image imgValue = null;
                    // 试图获得图片二进制数据并显示出来
                    object v = Args.DataSource.GetValue(this.XDataFieldName);
                    if (v != null && DBNull.Value.Equals(v) == false)
                    {
                        byte[] bsImageValue = v as byte[];
                        if (bsImageValue != null)
                        {
                            System.IO.MemoryStream ms = new System.IO.MemoryStream(bsImageValue);
                            imgValue = System.Drawing.Image.FromStream(ms);
                        }
                    }
                    this.Image = imgValue;
                    break;
                case XDataSourceEventStyle.ReadUI:
                    // 处理ReadUI事件，将显示的图片数据的二进制内容保存到数据源中
                    if (this.Image == null)
                    {
                        Args.DataSource.SetValue(this.XDataFieldName, null);
                    }
                    else
                    {
                        System.IO.MemoryStream ms = new System.IO.MemoryStream();
                        this.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                        byte[] bsValue = ms.ToArray();
                        Args.DataSource.SetValue(this.XDataFieldName, bsValue);
                    }
                    break;
            }
        }
    }//public class XDBPictureBox
}